"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

import graphene
from graphene_django import DjangoObjectType
from siriuso.api.mixins import SiriusoAuthNode, SiriusoObjectId, SiriusoPermissions
from graphene_permissions.permissions import AllowAny
from django.utils.translation import gettext_lazy as _

from graphene.types.generic import GenericScalar # Solution
from django.db.models import Sum
from django.db.models.functions import Cast
from django.db import models

from siriuso.api.filters import SiriusoFilterConnectionField
from siriuso.api.types import SiriusoLingvo
from ..models import *

from siriuso.utils import lingvo_kodo_normaligo, get_lang_kodo


class EnketoTipoNode(SiriusoAuthNode, DjangoObjectType):
    """
    Тип анкет
    """
    permission_classes = (AllowAny,)
    json_filter_fields = {
        'nomo__enhavo': ['contains', 'icontains'],
        'kodo': ['icontains', ]
    }

    nomo = graphene.Field(SiriusoLingvo, description=_('Наименование типа анкет'))

    class Meta:
        model = EnketoTipo
        filter_fields = {
            'uuid': ['exact'],
            'kodo': ['exact', 'icontains', 'istartswith'],
        }
        interfaces = (graphene.relay.Node,)


class InformojNode(SiriusoAuthNode, SiriusoObjectId, SiriusoPermissions, DjangoObjectType):
    """
    Поля анкеты
    """
    permission_classes = (AllowAny,)
    json_filter_fields = {
        'priskribo__enhavo': ['contains', 'icontains'],
        'nomo__enhavo': ['contains', 'icontains'],
    }

    nomo = graphene.Field(SiriusoLingvo, description=_('Название поля анкеты'))
    priskribo = graphene.Field(SiriusoLingvo, description=_('Описание поля анкеты'))
    # datumo = graphene.Field(SiriusoLingvo, description=_('Данные по умолчанию в поле анкеты'))
    datumo = GenericScalar()

    class Meta:
        model = Informoj
        filter_fields = {
            'uuid': ['exact'],
            'forigo': ['exact'],
            'arkivo': ['exact'],
            'publikigo': ['exact'],
            'enketo__uuid': ['exact'],
            # 'datumo': ['contains'],
        }
        interfaces = (graphene.relay.Node,)


class EnketoNode(SiriusoAuthNode, SiriusoObjectId, SiriusoPermissions, DjangoObjectType):
    """
    Анкеты
    """
    permission_classes = (AllowAny,)
    json_filter_fields = {
        'priskribo__enhavo': ['contains', 'icontains'],
        'nomo__enhavo': ['contains', 'icontains'],
    }

    nomo = graphene.Field(SiriusoLingvo, description=_('Наименование категории'))
    priskribo = graphene.Field(SiriusoLingvo, description=_('Описание категории'))

    informoj = SiriusoFilterConnectionField(InformojNode,
        description=_('Выводит поля анкеты'))

    class Meta:
        model = Enketo
        filter_fields = {
            'uuid': ['exact'],
            'forigo': ['exact'],
            'arkivo': ['exact'],
            'publikigo': ['exact'],
            'tipo__kodo': ['exact', 'icontains', 'istartswith'],
            'tipo__uuid': ['exact'],
        }
        interfaces = (graphene.relay.Node,)

    def resolve_informoj(self, info, **kwargs):
        return Informoj.objects.filter(enketo=self, forigo=False, arkivo=False, publikigo=True)


class EnketiInformojNode(SiriusoAuthNode, SiriusoPermissions, DjangoObjectType):
    """
    Заполненные поля анкеты
    """
    permission_classes = (AllowAny,)

    datumo = GenericScalar()

    class Meta:
        model = EnketiInformoj
        filter_fields = {
            'uuid': ['exact'],
            'forigo': ['exact'],
            'arkivo': ['exact'],
            'publikigo': ['exact'],
            'informoj__uuid': ['exact'],
            'enketi__uuid': ['exact'],
        }
        interfaces = (graphene.relay.Node,)


class EnketiNode(SiriusoAuthNode, SiriusoPermissions, DjangoObjectType):
    """
    Заполненные анкеты
    """
    permission_classes = (AllowAny,)

    enketi_informoj = SiriusoFilterConnectionField(EnketiInformojNode,
        description=_('Выводит заполненные поля анкеты'))

    summa = graphene.Float()

    class Meta:
        model = Enketi
        filter_fields = {
            'uuid': ['exact'],
            'forigo': ['exact'],
            'arkivo': ['exact'],
            'publikigo': ['exact'],
            'autoro__id': ['exact'],
            'enketo__uuid': ['exact'],
        }
        interfaces = (graphene.relay.Node,)

    def resolve_enketi_informoj(self, info, **kwargs):
        return EnketiInformoj.objects.filter(enketi=self, forigo=False, arkivo=False, publikigo=True)

    def resolve_summa(self, info, **kwargs):
        """
        План - функция суммирования всех полей, которые возможно суммировать
        Выбираем те поля, которые можно агрегировать согласно типа и по ним производим агрегацию суммирования
        """
        qs = EnketiInformoj.objects.filter(enketi=self, forigo=False, arkivo=False, publikigo=True
            ).values('datumo').aggregate(castos=Sum(Cast('datumo', models.FloatField())))
            #)#.values("castos"))
        # print('========================', qs['castos'])
        return qs['castos']


class EnketoQuery(graphene.ObjectType):
    enketo_tipoj = SiriusoFilterConnectionField(EnketoTipoNode,
                                                          description=_('Выводит все доступные типы Анкет'))
    enketo = SiriusoFilterConnectionField(EnketoNode,
                                                    description=_('Выводит все доступные Анкеты'))
    informoj = SiriusoFilterConnectionField(InformojNode,
                                                          description=_('Выводит все доступные поля Анкет'))
    enketi = SiriusoFilterConnectionField(EnketiNode,
                                                    description=_('Выводит все доступные заполненные Анкеты'))
    enketi_informoj = SiriusoFilterConnectionField(EnketiInformojNode,
                                                    description=_('Выводит все доступные заполненные поля Анкет'))
